package com.itcaius.weblog.admin.service.Impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.itcaius.weblog.admin.convert.WikiConvert;
import com.itcaius.weblog.admin.model.vo.wiki.*;
import com.itcaius.weblog.admin.service.AdminWikiService;
import com.itcaius.weblog.common.domain.dos.ArticleDO;
import com.itcaius.weblog.common.domain.dos.WikiCatalogDO;
import com.itcaius.weblog.common.domain.dos.WikiDO;
import com.itcaius.weblog.common.domain.mapper.ArticleMapper;
import com.itcaius.weblog.common.domain.mapper.WikiCatalogMapper;
import com.itcaius.weblog.common.domain.mapper.WikiMapper;
import com.itcaius.weblog.common.enums.ArticleTypeEnum;
import com.itcaius.weblog.common.enums.ResponseCodeEnum;
import com.itcaius.weblog.common.enums.WikiCatalogLevelEnum;
import com.itcaius.weblog.common.exception.BizException;
import com.itcaius.weblog.common.utils.PageResponse;
import com.itcaius.weblog.common.utils.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author Caius
 * @description
 * @since Created in 2025-06-21
 */
@Service
@Slf4j
public class AdminWikiServiceImpl implements AdminWikiService {

    @Autowired
    private WikiMapper wikiMapper;
    @Autowired
    private WikiCatalogMapper wikiCatalogMapper;
    @Autowired
    private ArticleMapper articleMapper;

    /**
     * 新增知识库
     * @param addWikiReqVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response addWiki(AddWikiReqVO addWikiReqVO) {
        WikiDO wikiDO = WikiDO.builder()
                .cover(addWikiReqVO.getCover())
                .title(addWikiReqVO.getTitle())
                .summary(addWikiReqVO.getSummary())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();

        wikiMapper.insert(wikiDO);

        Long wikiId = wikiDO.getId();

        wikiCatalogMapper.insert(WikiCatalogDO.builder().wikiId(wikiId).title("概述").sort(1).build());
        wikiCatalogMapper.insert(WikiCatalogDO.builder().wikiId(wikiId).title("基础").sort(2).build());
        return Response.success();
    }

    /**
     * 删除知识库
     * @param deleteWikiReqVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response deleteWiki(DeleteWikiReqVO deleteWikiReqVO) {
        Long wikiId = deleteWikiReqVO.getId();

        // 删除知识库
        int count = wikiMapper.deleteById(wikiId);

        if (count == 0) {
            log.warn("该知识库不存在， wikiId: {}", wikiId);
            throw new BizException(ResponseCodeEnum.WIKI_NOT_FOUND);
        }

        List<WikiCatalogDO> wikiCatalogDOS = wikiCatalogMapper.selectByWikiId(wikiId);
        List<Long> articleIds = wikiCatalogDOS.stream()
                .filter(wikiCatalogDO -> Objects.nonNull(wikiCatalogDO.getArticleId())
                        && Objects.equals(wikiCatalogDO.getLevel(), WikiCatalogLevelEnum.TWO.getValue()))
                .map(WikiCatalogDO::getArticleId)
                .collect(Collectors.toList());

        // 更新文章类型 type 为普通
        if (!CollectionUtils.isEmpty(articleIds)) {
            articleMapper.updateByIds(ArticleDO.builder()
                    .type(ArticleTypeEnum.NORMAL.getValue())
                    .build(), articleIds);
        }

        // 删除知识库目录
        wikiCatalogMapper.deleteByWikiId(wikiId);

        return Response.success();
    }

    /**
     * 知识库分页查询
     * @param findWikiPageListReqVO
     * @return
     */
    @Override
    public Response findWikiPageList(FindWikiPageListReqVO findWikiPageListReqVO) {
        Long current = findWikiPageListReqVO.getCurrentPage();
        Long size = findWikiPageListReqVO.getSize();

        String title = findWikiPageListReqVO.getTitle();
        LocalDate startDate = findWikiPageListReqVO.getStartDate();
        LocalDate endDate = findWikiPageListReqVO.getEndDate();

        Page<WikiDO> wikiDOPage = wikiMapper.selectPageList(current, size, title, startDate, endDate, null);

        List<WikiDO> wikiDOS = wikiDOPage.getRecords();

        List<FindWikiPageListRspVO> vos = null;
        if (!CollectionUtils.isEmpty(wikiDOS)) {
            vos  = wikiDOS.stream()
                    .map(articleDO -> WikiConvert.INSTANCE.convert2VO(articleDO))
                    .collect(Collectors.toList());
        }

        return PageResponse.success(wikiDOPage, vos);
    }

    /**
     * 更新知识库置顶状态
     * @param updateWikiIsTopReqVO
     * @return
     */
    @Override
    public Response updateWikiIsTop(UpdateWikiIsTopReqVO updateWikiIsTopReqVO) {
        Long wikiId = updateWikiIsTopReqVO.getId();
        Boolean isTop = updateWikiIsTopReqVO.getIsTop();

        Integer maxWeight = 0;

        if (isTop) {
            WikiDO wikiDO = wikiMapper.selectMaxWeight();
            Integer weight = wikiDO.getWeight();

            maxWeight = weight + 1;
        }

        wikiMapper.updateById(WikiDO.builder().id(wikiId).weight(maxWeight).build());

        return Response.success();
    }

    /**
     * 更新知识库发布状态
     * @param updateWikiIsPublishReqVO
     * @return
     */
    @Override
    public Response updateWikiIsPublish(UpdateWikiIsPublishReqVO updateWikiIsPublishReqVO) {
        Long wikiId = updateWikiIsPublishReqVO.getId();
        Boolean isPublish = updateWikiIsPublishReqVO.getIsPublish();

        wikiMapper.updateById(WikiDO.builder().id(wikiId).isPublish(isPublish).build());
        return Response.success();
    }

    @Override
    public Response updateWiki(UpdateWikiReqVO updateWikiReqVO) {
        WikiDO wikiDO = WikiDO.builder()
                .id(updateWikiReqVO.getId())
                .title(updateWikiReqVO.getTitle())
                .cover(updateWikiReqVO.getCover())
                .summary(updateWikiReqVO.getSummary())
                .build();

        wikiMapper.updateById(wikiDO);

        return Response.success();
    }

    /**
     * 查询知识库目录
     * @param findWikiCatalogListReqVO
     * @return
     */
    @Override
    public Response findWikiCatalogList(FindWikiCatalogListReqVO findWikiCatalogListReqVO) {
        Long wikiId = findWikiCatalogListReqVO.getId();

        // 查询知识库下所有目录
        List<WikiCatalogDO> wikiCatalogDOS = wikiCatalogMapper.selectByWikiId(wikiId);

        List<FindWikiCatalogListRspVO> vos = null;
        if (!CollectionUtils.isEmpty(wikiCatalogDOS)) {
            vos = Lists.newArrayList();

            // 提取一级目录
            List<WikiCatalogDO> level1Catalogs = wikiCatalogDOS.stream()
                    .filter(catalogDO -> Objects.equals(catalogDO.getLevel(), WikiCatalogLevelEnum.ONE.getValue())) // 一级目录
                    .sorted(Comparator.comparing(WikiCatalogDO::getSort)) // 升序排列
                    .collect(Collectors.toList());

            // 循环将 DO 转换为 VO
            for (WikiCatalogDO level1Catalog : level1Catalogs) {
                vos.add(FindWikiCatalogListRspVO.builder()
                        .id(level1Catalog.getId())
                        .articleId(level1Catalog.getArticleId())
                        .title(level1Catalog.getTitle())
                        .sort(level1Catalog.getSort())
                        .level(level1Catalog.getLevel())
                        .editing(Boolean.TRUE)
                        .build());
            }

            // 设置一级目录下面的二级目录
            vos.forEach(level1Catalog -> {
                Long parentId = level1Catalog.getId();
                // 提取二级目录
                List<WikiCatalogDO> level2CatalogDOS = wikiCatalogDOS.stream()
                        .filter(catalogDO -> Objects.equals(catalogDO.getParentId(), parentId)
                                && Objects.equals(catalogDO.getLevel(), WikiCatalogLevelEnum.TWO.getValue()))
                        .sorted(Comparator.comparing(WikiCatalogDO::getSort))
                        .collect(Collectors.toList());

                // 二级目录 DO 转 VO
                List<FindWikiCatalogListRspVO> level2Catalogs = level2CatalogDOS.stream()
                        .map(catalogDO -> FindWikiCatalogListRspVO.builder()
                                .id(catalogDO.getId())
                                .articleId(catalogDO.getArticleId())
                                .title(catalogDO.getTitle())
                                .level(catalogDO.getLevel())
                                .sort(catalogDO.getSort())
                                .editing(Boolean.FALSE)
                                .build())
                        .collect(Collectors.toList());
                level1Catalog.setChildren(level2Catalogs);
            });
        }
        return Response.success(vos);
    }
}
